<template>
	<div class="large-screen">
		<!-- 左侧文本框 -->

		<!-- <div class="details" v-if="articulations.length">

          <button @click="updated">更新</button>

          <el-input v-model="textarea" :rows="10" type="textarea" />

        </div> -->

		<!-- 右侧输入框 -->

		<div class="articulations" v-if="articulations.length">
			<div class="ariculation-name">
				<span
					v-for="(item, index) in articulations"
					:key="index"
					:class="[dataIndex === index ? 'active' : '']"
					@click="dataIndex = index"
					>{{ item.name }}</span
				>
			</div>

			<div class="ariculation-control1">
				<div v-for="item in articulations[dataIndex].stages" :key="item">
					<span>{{ item.name }}</span>

					<el-slider
						v-model="item.initialValue"
						:min="item.minimumValue"
						:max="item.maximumValue"
						:step="0.01"
						show-input
						size="small"
						@input="handleChange(item)"
					/>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup>
import { onMounted, ref, watch, toRefs, onBeforeUnmount } from 'vue'
import { useStore } from 'vuex'
import SocketMoudle from '@/views/js/SocketMoudle.js'
import { TestPosmodel } from '@/views/data/TestPosmodel.js'
import { modelPos } from '@/views/data/MainModelData.js'
import CollisionSystem from '@/views/js/CollisionSystem.js'
import { ArmData, agvData, xingjiaType01Data, xingjiaType02Data, xingjiaTypeTempData, GTYXData, PogoData } from '@/views/data/DeviceData.js'

import {
  InitSocket,
  getCollectData,
  updatedhandleData,
  ArmDataMap,
  AGVDataMap,
  XJDataMap,
  XJDataMap2,
  XJDataMapTemp,
  GYTXDataMap,
  PogoDataMap,
  socket,
  Create3DLable
} from '@/views/js/DataManger.js'
const store = useStore()
const { sandboxReady } = toRefs(store.state)
let outLine; let outLine2 = null
let transform
let collisionSystem = null
let currentSelectModel
let boxHelper
let boxEffect = null
const initPos = {
  cameraPos: [3, 71.7, -66.63],
  target: [1.3, -9.76, -3.51]
}

let models = []
let handleModel
// 点击更新
const dataIndex = ref(0)
const articulations = ref([])
// const modelPos = { x:-57.74473488421344, y: -1, z:52.79838394374601 };
onMounted(() => {
  watch(
    sandboxReady,
    async ready => {
      if (ready) {
        SetControls()
        transform = new GCMap.CustomTransform({
          sandbox: window.sandbox
        })
        window.sandbox.camera.position.set(...initPos.cameraPos)
        window.sandbox.controls.target.set(...initPos.target)
        const axesHelper = new GC.AxesHelper(5)
        axesHelper.position.set(0, 0.2, 0)
        window.sandbox.scene.add(axesHelper)
        outLine = new GCMap.OutLine2({
          sandbox: window.sandbox,
          color: 0xe91010
        })
        outLine2 = new GCMap.OutLine2({
          sandbox: window.sandbox,
          color: 0x00ffff
        })
        loadMainmodel()
        OnShadow()
        startCollisionSystem()
      }
    },
    { immediate: true }
  )
})

function startCollisionSystem () {
  // 使用示例
  collisionSystem = new CollisionSystem()
  // 在动画循环中更新
  function animate () {
    collisionSystem.update()
    requestAnimationFrame(animate)
  }
  animate()
}

async function addModels () {
  handleModel = await new GCMap.GltfModel2({
    sandbox: window.sandbox,
    // url: "./models/Arm06.gltf",
    url: './models/AGV.gltf',
    isChangeMatMetal: true
  })
  articulations.value = handleModel.model.userData.gltfExtensions.AGI_articulations.articulations
  window.sandbox.logger.log('model', handleModel)
  const result = null
  handleModel.on('doubleClick', e => {
    window.sandbox.logger.log('模型', handleModel)
    outLine.add(e.pickedRootNodes)
  })

  // const agv_pose = {
  //   "整体 MoveX": 20,
  //   "整体 MoveY": 0,
  //   "整体 MoveZ": 0,
  //   "整体 yRoll": 90,
  // };
  // updatedhandleData(agv_pose,handleModel);
  // handleModel.on("rightClick", (e) => {
  //    window.sandbox.logger.log("模型", handleModel);
  //   outLine.add(e.rootNode);
  //   addTransformControlsMesh02(handleModel.model.scene);
  // });
  // handleModel.zoomTo();
}

function handleChange (item) {
  // key=一节臂-大臂 yRoll
  const key = articulations.value[dataIndex.value].name + ' ' + item.name
  // const zoom = item.unit || 1;
  handleModel.setArticulationStage(key, item.initialValue, false)
  // handleModel.applyArticulations()
}

const textarea = ref('')
watch(
  articulations,
  () => {
    let str = '{'
    articulations.value.forEach(item => {
      item.stages.forEach(j => {
        str += `"${item.name} ${j.name}":${j.initialValue},\n`
      })
    })
    textarea.value = `${str}}`
  },
  { deep: true }
)

function updated () {
  const arr = textarea.value.split('\n')
  let jsonString = arr.join('')
  jsonString = jsonString.replace(/,\s*(?=})/g, '') // 移除字符串中的逗号后的空格
  const obj = JSON.parse(jsonString)

  Object.keys(obj).forEach(key => {
    handleModel.setArticulationStage(key.trim(), obj[key] - 0)
    // handleModel.applyArticulations()

    // 更新表单
    articulations.value.forEach(item => {
      const name = key.split(' ')
      if (item.name === name[0]) {
        window.sandbox.logger.log(item)
        item.stages.forEach(s => {
          if (s.name === name[1]) {
            s.initialValue = obj[key] - 0
          }
        })
      }
    })
  })
}
let control = null

function addTransformControlsMesh02 (model) {
  const orbit = window.sandbox.controls
  const scene = window.sandbox.scene
  let currentCamera = window.sandbox.camera
  const renderer = window.sandbox.renderer
  const PosArry = []

  if (control) {
    control.attach(model)
  } else {
    control = new GC.TransformControls(currentCamera, renderer.domElement)
    const gizmo = control.getHelper()
    scene.add(gizmo)
    control.attach(model)

    control.addEventListener('change', () => {
      renderer.render(scene, currentCamera) // 实时更新渲染
    })
    control.addEventListener('dragging-changed', function (event) {
      orbit.enabled = !event.value
    })
    control.addEventListener('mouseUp', () => {
      orbit.enableRotate = true
      window.sandbox.logger.log(model.position, model.rotation, model.scale)
      PosArry.push(model.position)
      // 获取欧拉角的弧度值
      const rotationRad = model.rotation
      // 转换为度数
      const rotationDeg = {
        x: GC.MathUtils.radToDeg(rotationRad.x),
        y: GC.MathUtils.radToDeg(rotationRad.y),
        z: GC.MathUtils.radToDeg(rotationRad.z)
      }
    })

    window.addEventListener('keydown', function (event) {
      switch (event.key) {
        case 'q':
          control.setSpace(control.space === 'local' ? 'world' : 'local')
          break

        case 'Shift':
          control.setTranslationSnap(1)
          control.setRotationSnap(GC.MathUtils.degToRad(15))
          control.setScaleSnap(0.25)
          break

        case 'w':
          control.setMode('translate')
          break

        case 'e':
          control.setMode('rotate')
          break

        case 'r':
          control.setMode('scale')
          break

        case 'c':
          const position = currentCamera.position.clone()

          currentCamera = currentCamera.isPerspectiveCamera ? cameraOrtho : cameraPersp
          currentCamera.position.copy(position)

          orbit.object = currentCamera
          control.camera = currentCamera

          currentCamera.lookAt(orbit.target.x, orbit.target.y, orbit.target.z)
          onWindowResize()
          break

        case 'v':
          const randomFoV = Math.random() + 0.1
          const randomZoom = Math.random() + 0.1

          cameraPersp.fov = randomFoV * 160
          cameraOrtho.bottom = -randomFoV * 500
          cameraOrtho.top = randomFoV * 500

          cameraPersp.zoom = randomZoom * 5
          cameraOrtho.zoom = randomZoom * 5
          onWindowResize()
          break

        case '+':
        case '=':
          control.setSize(control.size + 0.1)
          break

        case '-':
        case '_':
          control.setSize(Math.max(control.size - 0.1, 0.1))
          break

        case 'x':
          control.showX = !control.showX
          break

        case 'y':
          control.showY = !control.showY
          break

        case 'z':
          control.showZ = !control.showZ
          break

        case ' ':
          control.enabled = !control.enabled
          break

        case 'Escape':
          control.reset()
          break
      }
    })
  }
}

function OnShadow () {
  const lightIntensity = { intensity: 3 }
  const ambient = new GC.AmbientLight(0xffffff, 3.5)
  window.sandbox.scene.add(ambient)
  models.push(ambient)

  const directionalLight = new GC.DirectionalLight(0xffffff, lightIntensity.intensity)
  models.push(directionalLight)
  directionalLight.position.set(0, 10, 0)
  window.sandbox.scene.add(directionalLight)
  window.sandbox.renderer.shadowMap.enabled = true // 启用阴影
  window.sandbox.renderer.shadowMap.type = GC.PCFSoftShadowMap // 更柔和的阴影（可选）

  directionalLight.castShadow = true // 启用光源阴影
  directionalLight.position.set(-28, 47, -53)
  // addTransformControlsMesh02(directionalLight);

  // 调整阴影参数（优化阴影质量）
  directionalLight.shadow.mapSize.width = 2048 // 阴影贴图分辨率
  directionalLight.shadow.mapSize.height = 2048
  directionalLight.shadow.camera.near = 0.01 // 阴影计算范围
  directionalLight.shadow.camera.far = 5000

  const distance = 60
  directionalLight.shadow.camera.left = -distance
  directionalLight.shadow.camera.right = distance
  directionalLight.shadow.camera.top = distance
  directionalLight.shadow.camera.bottom = -distance

  // const shadowHelper = new GC.CameraHelper(directionalLight.shadow.camera);
  // scene.add(shadowHelper); //
}

// 销毁
function destroyModels () {
  models?.forEach(model => {
    if (typeof model?.destroy === 'function') {
      model.destroy() // 确保 destroy 是函数才调用
    }
    if (model?.isObject3D) {
      window.sandbox?.scene?.remove(model)
    }
  })

  // 清空数组引用
  models.length = 0
  models = []
  ArmDataMap.clear()
  AGVDataMap.clear()
  if (socket !== null) {
    socket.Close()
  }
  if (boxEffect !== null) {
    boxEffect.destroy()
    boxEffect = null
  }
  if (outLine) {
    outLine.clear()
    outLine = null
  }
}
document.addEventListener('keydown', e => {
  if (e.key === 'a') {
    destroyModels()
  }
  if (e.key === ' ') {
    ResetCamera()
  }
})

const XJmodels = []
async function loadMainmodel () {
  TestPosmodel.forEach(async item => {
    const handleModel = await new GCMap.GltfModel({
      sandbox: window.sandbox,
      url: window.modelUrl + item.dataPath,
      isChangeMatMetal: true,
      isAddScene: true,
      isCastShadow: item.isCastShadow,
      isReceiveShadow: item.isReceiveShadow,
      position: item.position,
      rotation: item.rotation,
      enableClearCoatMat: item.enableClearCoatMat || false
    })
    // testPosion(handleModel)
    // if (!(item.name === '小范围' || item.name === '裁剪大范围')) {
    //   testPosion(handleModel)
    // }

    models.push(handleModel.model.scene)
    handleModel.on('doubleClick', e => {
      window.sandbox.logger.log('模型', handleModel)
      window.sandbox.logger.log('根节点', e.rootNode)
      ShowClickEffect(item, handleModel.model.scene)
    })
  })

  // XJmodels = await loadAllModels2(XJData, true);

  Create3DLable((target, id) => {})

  const agvmodels = await loadAllModels(agvData, AGVDataMap, true)

  // const childNode = XJmodels[0].model.scene;
  // agvmodels.forEach((item) => {
  //   const parentNode = item.model.scene;
  //   parentNode.addEventListener("collisionenter", (e) => {
  //      window.sandbox.logger.log(item.modelName, "开始碰撞:", e.other);
  //     attachChildKeepTransform(parentNode.children[0], childNode);
  //   });
  // });

  //  window.sandbox.logger.log("agv加载成功", AGVDataMap);

  await loadAllModels(ArmData, ArmDataMap, false, false)
  await loadAllModels(xingjiaType01Data, XJDataMap, false, false)
  await loadAllModels(xingjiaType02Data, XJDataMap2, false, false)
  await loadAllModels(GTYXData, GYTXDataMap, false, false)

  await loadAllModels(xingjiaTypeTempData, XJDataMapTemp, false, false)

  await loadAllModels(PogoData, PogoDataMap, false, false)

  //  window.sandbox.logger.log("机械臂加载成功", ArmDataMap);

  await getCollectData()

  window.sandbox.logger.log('初始化设备完毕...')
  InitSocket()

  // handleModel = AgvDataModels[0];
  // articulations.value =
  //   handleModel.model.userData.gltfExtensions.AGI_articulations.articulations;
}

function findRootNode (object) {
  // 如果对象没有父级，或者父级是场景，则认为是根节点
  if (!object.parent || object.parent instanceof GC.Scene) {
    return object
  }
  return findRootNode(object.parent)
}

function attachChildKeepTransform (parent, child) {
  // 确保使用 GC 而不是 GC（如果你实际使用的是 THREE）
  const worldPos = child.getWorldPosition(new GC.Vector3())
  const worldQuat = new GC.Quaternion()
  child.getWorldQuaternion(worldQuat)

  // 附加到父物体
  parent.add(child)

  // 设置局部位置
  const localPos = parent.worldToLocal(worldPos.clone())
  child.position.copy(localPos)

  // 设置局部旋转 - 修正后的版本
  const parentWorldQuat = new GC.Quaternion()
  if (parent.matrixWorld) {
    parent.updateMatrixWorld() // 确保矩阵是最新的
    parentWorldQuat.setFromRotationMatrix(parent.matrixWorld)
  }

  // 计算局部旋转
  const inverseParentQuat = new GC.Quaternion().copy(parentWorldQuat).invert()
  child.quaternion.copy(worldQuat).premultiply(inverseParentQuat)

  // 更新矩阵
  child.updateMatrixWorld()
}
const AllModelTypeMap = new Map() // 存储已加载的模型
const loadingPromises = new Map() // 存储正在加载的Promise
async function loadAllModels (ModelData, modelMap, isCalculateCol = false, isTestpos = false) {
  // 使用for...of循环按顺序处理，确保前一个模型的加载完成后再处理下一个
  for (const item of ModelData) {
    try {
      // window.sandbox.logger.log('开始处理模型:', item.dataPath);
      let handleM = null

      // 检查是否已经有加载完成的模型
      if (AllModelTypeMap.has(item.dataPath)) {
        const handleTemp = AllModelTypeMap.get(item.dataPath)
        handleM = await GetCloneModel(item, handleTemp)
        // window.sandbox.logger.log("克隆物体:", item.dataPath);
      }
      // 检查是否正在加载中
      else if (loadingPromises.has(item.dataPath)) {
        window.sandbox.logger.log('等待已开始的加载:', item.dataPath)
        await loadingPromises.get(item.dataPath)

        // 加载完成后应该已经存入AllModelTypeMap
        const handleTemp = AllModelTypeMap.get(item.dataPath)
        handleM = await GetCloneModel(item, handleTemp)
      }
      // 需要全新加载
      else {
        // 创建并存储加载Promise
        const loadPromise = new GCMap.GltfModel2({
          sandbox: window.sandbox,
          url: window.modelUrl + item.dataPath,
          itemData: item,
          isChangeMatMetal: true,
          isAddScene: true,
          isCastShadow: item.isCastShadow || true,
          isReceiveShadow: item.isReceiveShadow,
          position: item.position,
          rotation: item.rotation,
          label: item.id,
          fontOffect: item.fontOffect || { x: 0, y: 0, z: 0 },
          isShowLable: item.isShowLable || false,
          enableClearCoatMat: item.enableClearCoatMat || false
        }).then(loadedModel => {
          AllModelTypeMap.set(item.dataPath, loadedModel)
          // window.sandbox.logger.info("存储模型:", item.dataPath);
          return loadedModel
        })

        loadingPromises.set(item.dataPath, loadPromise)
        handleM = await loadPromise

        // 加载完成后从loadingPromises移除
        loadingPromises.delete(item.dataPath)
      }

      modelMap.set(item.id, handleM)

      // 事件处理和其他逻辑...
      handleM.on('doubleClick', e => {
        window.sandbox.logger.log('模型', item, handleM.model.userData)
        ShowOutLineEffect(item, e.rootNode)
        if (item.idDevice) {
          if (handleModel) {
            handleModel.isclick = false
          }
        }
        handleModel = handleM
        if (item.idDevice) {
          handleModel.isclick = true
        }

        dataIndex.value = 0
        articulations.value = handleModel.model.userData.gltfExtensions.AGI_articulations.articulations

        // addTransformControlsMesh02(handleM.overlay);
      })
      handleM.on('mouseenter', (e) => {
        if (!item.idDevice) return
        if (handleM.isclick) return
        console.log('进入', item.id)
        outLine2.add(e.rootNode)
      })
      handleM.on('mouseleave', (e) => {
        if (!item.idDevice) return
        if (handleM.isclick) return
        console.log('离开', item.id)
        outLine2.remove(e.rootNode)
      })
      if (item.type === 'fixture' || item.type === 'fixture2') {
        let banzi = null
        if (handleM.model.scene) {
          banzi = handleM.model.scene.getObjectByName('banzi')
        } else {
          banzi = handleM.model.getObjectByName('banzi')
        }
        if (item.isHasBanzi) {
          banzi.visible = true
        } else {
          banzi.visible = false
        }
      }
      if (isTestpos) testPosion(handleM)
      // if (isCalculateCol) collisionSystem.addObject(handleM.model.scene);
      //  window.sandbox.logger.log("模型", handleM);
      models.push(handleM)
      setTimeout(() => {
        if (item.originaOffectlPose) {
          updatedhandleOriginData(item.originaOffectlPose, handleM)
        }
      }, 0)
      setTimeout(() => {
        updatedhandleData(item.pose, handleM, false)
      }, 0)
    } catch (error) {
      window.sandbox.logger.error(`加载模型 ${item.dataPath} 出错:`, error)
    }
  }
}

async function GetCloneModel (item, handleTemp) {
  const handle = await new GCMap.GltfModelClone2({
    sandbox: window.sandbox,
    isChangeMatMetal: true,
    isAddScene: true,
    isCastShadow: item.isCastShadow || true,
    isReceiveShadow: item.isReceiveShadow,
    position: item.position,
    rotation: item.rotation,
    gltfModel: handleTemp,
    label: item.id,
    fontOffect: item.fontOffect || { x: 0, y: 0, z: 0 },
    isShowLable: item.isShowLable || false,
    enableClearCoatMat: item.enableClearCoatMat || false
  })
  return handle
}

async function loadAllModels2 (ModelData, isCalculateCol = false, isTestpos = false) {
  const loadPromises = ModelData.map(async item => {
    const handleM = await new GCMap.GltfModel({
      sandbox: window.sandbox,
      url: window.modelUrl + item.dataPath,
      isChangeMatMetal: true,
      isAddScene: true,
      isCastShadow: item.isCastShadow,
      isReceiveShadow: item.isReceiveShadow,
      position: item.position,
      rotation: item.rotation
    })
    if (isTestpos) {
      testPosion(handleM)
    }

    models.push(handleM.model.scene)
    handleM.on('doubleClick', e => {
      window.sandbox.logger.log('模型', handleM)
      outLine.add(e.rootNode)
    })
    if (isCalculateCol) {
      collisionSystem.addObject(handleM.model.scene)
    }

    testPosion(handleM)
    return handleM
  })
  return await Promise.all(loadPromises)
}

// 更新原点
function updatedhandleOriginData (obj, handleM) {
  Object.keys(obj).forEach(key => {
    handleM.setArticulationOriginData(key.trim(), obj[key] - 0)
  })
}

function testPosion (model) {
  let { x, y, z } = model.position
  const heading = model.heading
  let pitch = model.pitch
  let roll = model.roll
  const highPrecision = 0.01
  const lowPrecision = 1
  let precesion = lowPrecision

  const highHeightPrecision = 0.1
  const lowHeightPrecision = 1
  let height = lowHeightPrecision
  document.addEventListener('keydown', e => {
    switch (e.key) {
      case 'h':
        precesion = highPrecision
        height = highHeightPrecision
        break
      case 'l':
        precesion = lowPrecision
        height = lowHeightPrecision
        break
      case 'ArrowUp':
        z -= precesion
        break
      case 'ArrowDown':
        z += precesion
        break
      case 'ArrowLeft':
        x -= precesion
        break
      case 'ArrowRight':
        x += precesion
        break
      case '1':
        y += precesion
        break
      case '4':
        y -= precesion
        break
        // case "2":
        //   heading += 1;
        //   break;
        // case "5":
        //   heading -= 1;
        //   break;
        // case "3":
        //   pitch += 1;
        //   break;
      case '6':
        pitch -= 1
        break
      case '7':
        roll += 1
        break
      case '8':
        roll -= 1
        break
			// case "m":
			//   socket.Close();
			//   break;
			// case "n":
			//   socket.startSocket();
			//   break;
    }
    model.position = { x, y, z }
    model.heading = heading
    model.pitch = pitch
    model.roll = roll
    window.sandbox.logger.log({ x, z, y, heading, pitch, roll })
  })
}
addEventListener()

function addEventListener () {
  document.addEventListener('keydown', e => {
    switch (e.key) {
      case 'm':
        socket.Close()
        break
      case 'n':
        socket.startSocket()
        break
    }
  })
}

function SetControls () {
  window.sandbox.logger.log('设置范围')
  const controls = window.sandbox.controls
  // 自动旋转
  controls.autoRotate = false
  controls.enableZoom = true
  // 设置阻尼
  controls.enableDamping = true
  controls.dampingFactor = 0.5

  // 设置是否围绕鼠标中心点旋转 false为围绕鼠标旋转
  controls.screenSpacePanning = false

  // 限制距离
  controls.minDistance = 0
  controls.maxDistance = 500

  // controls.minAzimuthAngle = -Math.PI / 4; // -45度
  // controls.maxAzimuthAngle = Math.PI / 4; // 45度

  // 限制垂直旋转角度（极角，单位：弧度）
  controls.minPolarAngle = 0 // 45度（从顶部算起）
  controls.maxPolarAngle = (Math.PI * 3) / 7 // 135度（从顶部算起）

  controls.enablePan = true // 默认 true（允许水平移动）
  // 限制水平移动范围
  controls.minTargetRadius = 0
  controls.maxTargetRadius = 200

  controls.minZoom = 0
  controls.maxZoom = 10
}

onBeforeUnmount(() => {
  destroyModels()
})

//  window.sandbox.logger.log("接收数据", obj);
//   Object.entries(obj).forEach(([key, value]) => {
//     // 处理每个键值对
//     //  window.sandbox.logger.log(key, value);
//     const type = getDeviceType(key)
//      window.sandbox.logger.log(type)
//     switch (type) {
//       case 'robot':
//         RefreshRobotData(key, value, true)
//         break
//       case 'AGV':
//         RefreshAGVData(value, true)
//         break
//     }
//   })

// 点击特效
function ShowBoundingBox (item, model) {
  const boundingBox = new GC.Box3().setFromObject(model)
  const size = boundingBox.getSize(new GC.Vector3())
  const center = boundingBox.getCenter(new GC.Vector3())

  // 如果点击的是当前已选中的模型
  if (currentSelectModel === item.dataPath) {
    // 如果已有包围盒，则销毁
    if (boxHelper) {
      window.sandbox.scene.remove(boxHelper)
      boxHelper = null
    }
    currentSelectModel = null
    return
  }

  // 如果点击的是不同模型
  if (boxHelper) {
    // 更新包围盒数据
    boxHelper.box.copy(boundingBox)
  } else {
    // 创建新包围盒
    boxHelper = new GC.Box3Helper(boundingBox, 0xffff00)
    window.sandbox.scene.add(boxHelper)
  }

  currentSelectModel = item.dataPath
}
async function ShowClickEffect (item, model) {
  // 如果点击的是当前已选中的模型
  if (currentSelectModel === item.dataPath) {
    // 如果已有特效，则销毁
    if (boxEffect) {
      boxEffect.destroy()
      boxEffect = null
    }
    currentSelectModel = null
    return
  }

  // 如果点击的是不同模型，先销毁旧特效
  if (boxEffect) {
    boxEffect.destroy()
    boxEffect = null
  }

  // 创建新特效
  currentSelectModel = item.dataPath
  const boundingBox = new GC.Box3().setFromObject(model)
  const size = boundingBox.getSize(new GC.Vector3())
  const center = boundingBox.getCenter(new GC.Vector3())

  boxEffect = await new GCMap.BoxEffect({
    sandbox: window.sandbox,
    speed: 0.5,
    position: center,
    scale: [...size],
    width: 0.5
  })

  // 添加双击事件监听
  boxEffect.on('doubleClick', handleDoubleClick)
}

function ShowOutLineEffect (item, model) {
  // 如果点击的是当前已选中的模型
  if (currentSelectModel === item.id) {
    // 如果已有包围盒，则销毁
    outLine.clear()
    currentSelectModel = null
    return
  }
  // if(!outLine)return
  // 如果点击的是不同模型
  outLine2.clear()
  outLine.clear()
  outLine.add(model)
  currentSelectModel = item.id
}

function handleDoubleClick (e) {
  // console.log("点击特效", e);
  if (boxEffect) {
    boxEffect.off('doubleClick', handleDoubleClick)
    boxEffect.destroy()
    boxEffect = null
    currentSelectModel = null
  }
}
</script>

<style lang="less">
.large-screen {
	.model-name {
		position: absolute;
		top: 1%;
		right: 45%;
		font-size: 20px;
		font-weight: 900;
		color: red;
	}
	.details {
		position: absolute;
		top: 5%;
		right: 41%;
		pointer-events: auto;
	}
	.articulations {
		text-align: center;
		user-select: none;
		pointer-events: auto;
		position: absolute;
		top: 10px;
		right: 20px;
		z-index: 1;
		width: 35%; // background-color: rgba(38, 101, 155, 0.3);
		background-color: rgba(1, 1, 1, 0.3);
		display: flex;
		color: #e6e6e6;
		max-height: 50vh;
		.ariculation-name {
			display: flex;
			flex-wrap: wrap;
			justify-content: space-between;
			width: 25%;
			background-color: rgba(3, 17, 34, 0.765);
			overflow: auto;
			&::-webkit-scrollbar {
				display: none;
			}
			span {
				width: 100%;
				display: block;
				line-height: 25px;
				background-color: rgb(98, 114, 114);
				margin: 4px;
				padding: 0 5px;
				cursor: pointer;
				&:hover {
					background-color: rgb(73, 108, 160);
				}
			}
			.active {
				background-color: rgb(29, 79, 155);
			}
		}
		.ariculation-control1 {
			flex: 1;
			.el-slider__input {
				width: 100px;
			}
		}
	}
}
</style>
